package service;

import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import server.AuctionServer;
import server.AuctionServerThread;

import domain.Auction;
import domain.GroupBid;
import domain.User;

public class GroupBidHolder {

	private static ArrayList<GroupBid> activeGroupBids;
	private static final Object singletonObject = new Object();
	private static GroupBidHolder instance;
	private static Timer timer = new Timer();
	
	
	private GroupBidHolder() {
		activeGroupBids = new ArrayList<GroupBid>();
	}
	
	public static GroupBidHolder getInstance(){
		if(instance == null){
			synchronized (singletonObject) {
				if(instance == null) instance = new GroupBidHolder();
			}
		}
		return instance;
	}
	
	public void removeGroupBid(GroupBid groupBid){
		synchronized (this) {
			activeGroupBids.remove(groupBid);
		}
	}
	
	public String getGroupBidList(){
		String groupBidList = "";
		
		synchronized (this) {
			for (int i = 0; i < activeGroupBids.size(); i++) {
				if(i<activeGroupBids.size()-1) groupBidList += activeGroupBids.get(i).toString()+"\n";
				else groupBidList += activeGroupBids.get(i).toString();
				
			}
		}
		if(groupBidList.equals("")) groupBidList = "No GroupBids.";
		
		return groupBidList+"\n*endlist*";
	}
	
	public String getGroupUser(String owner){
		String groupUser = "";
		synchronized (this) {
			for (int i = 0; i < activeGroupBids.size(); i++) {
				if(owner.equals(activeGroupBids.get(i).getOwner())){
					for (int j = 0; j < activeGroupBids.get(i).getGroupUser().size(); j++) {
						groupUser += activeGroupBids.get(i).getGroupUser().get(j) + " ";
					}
				}				
			}
		}
		
		return groupUser;
	}
	
	
	
	/**
	 * @return the activeGroupBids
	 */
	public GroupBid getCertainGroupBid(String owner) {
		GroupBid groupBid = null;
		synchronized (this) {
			for (int i = 0; i < activeGroupBids.size(); i++) {
				if(owner.equals(activeGroupBids.get(i).getOwner())){
					groupBid = activeGroupBids.get(i);
				}				
			}
		}		
		return groupBid;
	}

	/**
	 * @return the activeGroupBids
	 */
	public static ArrayList<GroupBid> getActiveGroupBids() {
		return activeGroupBids;
	}

	/**
	 * @param activeGroupBids the activeGroupBids to set
	 */
	public static void setActiveGroupBids(ArrayList<GroupBid> activeGroupBids) {
		GroupBidHolder.activeGroupBids = activeGroupBids;
	}

	public String getAuctionId(String owner){
		String auctionId = "";
		
		synchronized (this) {
			for (int i = 0; i < activeGroupBids.size(); i++) {
				if(owner.equals(activeGroupBids.get(i).getOwner())){
					auctionId += activeGroupBids.get(i).getAuctionId();
				}				
			}
		}
		
		return auctionId;
	}
	
	public void removeCertainGroupBid(String owner){
		synchronized (this) {
			for (int i = 0; i < activeGroupBids.size(); i++) {
				if(owner.equals(activeGroupBids.get(i).getOwner())){
					activeGroupBids.remove(i);
				}
			}
		}
	}
	
	public String getPrice(String owner){
		String price = "";
		
		synchronized (this) {
			for (int i = 0; i < activeGroupBids.size(); i++) {
				if(owner.equals(activeGroupBids.get(i).getOwner())){
					price += activeGroupBids.get(i).getPrice();
				}				
			}
		}
		
		return price;
	}
	
	public int getGroupUserCount(String owner){
		int x = 0;
		synchronized (this) {
			for (int i = 0; i < activeGroupBids.size(); i++) {
				if(owner.equals(activeGroupBids.get(i).getOwner())){
					for (int j = 0; j < activeGroupBids.get(i).getGroupUser().size(); j++) {
						x++;
					}
				}				
			}
		}	
		return x;
	}
	
	public boolean checkGroupBidOwner(String owner){
		boolean check = false;
		
		for (int i = 0; i < activeGroupBids.size(); i++) {
			if(owner.equals(activeGroupBids.get(i).getOwner())){
				check = true;
			}
		}
		
		
		return check;
	}
	
	public boolean checkConfirmedBid(String owner, double bid){
		boolean check = false;
		
		for (int i = 0; i < activeGroupBids.size(); i++) {
			if(owner.equals(activeGroupBids.get(i).getOwner())){
				if(activeGroupBids.get(i).getPrice() == bid){
					check = true;
				}				
			}
		}
		
		
		return check;
	}
	
	public boolean checkGroupBidId(int id){
		boolean check = false;
		
		for (int i = 0; i < activeGroupBids.size(); i++) {
			if(activeGroupBids.get(i).getAuctionId() == id){
				check = true;
			}
		}
		
		
		return check;
	}
	
	public void add(final GroupBid groupBid){
		synchronized (this) {
			activeGroupBids.add(groupBid);
			
//			timer.schedule(new TimerTask(){
//
//				@Override
//				public void run() {
//					removeGroupBid(groupBid);
//					for (int i = 0; i < activeGroupBids.size(); i++) {
//						if(activeGroupBids.get(i).getOwner().equals(groupBid.getOwner())){
//						 	activeGroupBids.get(i).setOverun(true);
//						}
//					}
//				}
//				
//			}, new Date(new Date().getTime()+20000));		
		}
	}
	
	public boolean checkTwiceConfirmed(int auctionId){
		boolean check = false;
		for (int i = 0; i < activeGroupBids.size(); i++) {
			if(auctionId == activeGroupBids.get(i).getAuctionId()){
				if(activeGroupBids.get(i).getGroupUser().size() >= 2){
					check = true;
				}
			}
		}
		
		
		return check;
	}
	
	
	public boolean addConfirmation(int id, double bid, String username){
		boolean isfull = false;
		
		synchronized (this) {
			for (int i = 0; i < activeGroupBids.size(); i++) {
				if(checkTwiceConfirmed(id) == false){
					if(id == activeGroupBids.get(i).getAuctionId()){
						activeGroupBids.get(i).getGroupUser().add(username);
						
					}					
				}
				if(checkTwiceConfirmed(id) == true){
					isfull = true;
				} else {
					isfull = false;
				}
			}
		}
		return isfull;
	}
	
	public GroupBid bid(int id, double bid, String username, AuctionServerThread thread){
		GroupBid result = null;
		
		synchronized (this) {
			for(int i=0; i<activeGroupBids.size(); i++){
				if(id==activeGroupBids.get(i).getAuctionId()) {
					
					if(bid>activeGroupBids.get(i).getPrice()) {
						thread.setOldBidder(activeGroupBids.get(i).getOwner());
						activeGroupBids.get(i).setPrice(bid);
						activeGroupBids.get(i).setOwner(username);
					}
					
					result = activeGroupBids.get(i);
					break;
				}	
			}
		}
		
		return result;
	}



}
